6.4 Ereignisse in der Vererbung  
In der Vererbungskette nehmen Ereignisse eine besondere Stellung ein. Um dies zu verdeutlichen, ist im folgenden Codefragment die Klasse ClassA definiert, die das Ereignis Hallo veröffentlicht.
| Class ClassA
|
| Public Delegate Sub MyHandler()
|
| Public Event Hallo As MyHandler
|
| Public Sub DoSomething()
|
| RaiseEvent Hallo()
|
| End Sub
|
| End Class
|
Wie üblich wird ein Delegat definiert und anschließend das Ereignis vom Typ des Delegaten deklariert. Ausgelöst wird das Ereignis beim Aufruf von DoSomething. In der Methode Main wird jetzt zu Testzwecken ein Objekt vom Typ der ClassA erzeugt und das Ereignis Hallo an den Ereignisempfänger MyTestMethod gebunden:
| Module Module1
|
| Sub Main()
|
| Dim obj As New ClassA
|
| AddHandler obj.Hallo, AddressOf MyTestMethod
|
| obj.DoSomething()
|
| Console.ReadLine()
|
| End Sub
|
| Public Sub MyTestMethod()
|
| Console.WriteLine("Ereignis ist ausgelöst.")
|
| End Sub
|
| End Module
|
Der Aufruf von DoSomething auf das ClassA-Objekt bewirkt, dass die vom Delegaten beschriebene Methode MyTestMethod ausgeführt und im Konsolenfenster
angezeigt wird.
Nun soll ClassB die Klasse ClassA ableiten. ClassB wird um die objektspezifische Methode DoSomething2 ergänzt, deren Aufruf ebenfalls die Auslösung des Ereignisses Hallo bewirkt. Unter der Annahme, dass sich ein Ereignis an die ableitende Klasse vererbt, könnte die Auslösung des Ereignisses Hallo folgendermaßen implementiert werden:
| Class ClassB
|
| Inherits ClassA
|
| Public Sub DoSométhing2()
|
| RaiseEvent Hallo()
|
| End Sub
|
| End Class
|
Wenn Sie versuchen, diesen Code zu schreiben, werden Sie jedoch sofort feststellen, dass hinter RaiseEvent das Ereignis Hallo nicht angeboten wird. Der Grund dafür ist, dass Ereignisse immer an die Klasse gebunden sind, in der sie definiert sind.
|
Ein Ereignis kann nur in der ereignisdefinierenden Klasse ausgelöst werden und nicht in einer abgeleiteten Klasse.
|
Damit stellt sich die Frage, wie wir das Ereignis einer Basisklasse einer abgeleiteten Klasse zur Verfügung stellen können.
Die Lösung ist sehr einfach: Wir implementieren eine zusätzliche Methode in die Klasse, in der das Ereignis definiert ist. In der Methode lösen wir das Ereignis aus. In unserem Beispiel müssten wir demnach die Klasse ClassA wie folgt ergänzen bzw. ändern:
| Class ClassA
|
| Public Delegate Sub MyHandler()
|
| Public Event Hallo As MyHandler
|
| Public Sub DoSomething()
|
| OnHallo()
|
| End Sub
|
| Public Sub OnHallo()
|
| RaiseEvent Hallo()
|
| End Sub
|
| End Class
|
Die Methode OnHallo berücksichtigt jetzt die Bedürfnisse einer ableitenden Klasse. In OnHallo wird das Ereignis Hallo ausgelöst, was keine Komplikationen mehr verursacht, da das Ereignis in derselben Klasse definiert ist. Außerdem wird die Methode OnHallo nun auch aus der Methode DoSomething heraus aufgerufen, was allerdings nicht zwingend notwendig ist.
Kommen wir zurück zur abgeleiteten Klasse ClassB. In Kenntnis der Methode OnHallo sollte die Anweisung in der Methode DoSomething2 wie folgt aussehen:
| Class ClassB
|
| Inherits ClassA
|
| Public Sub DoSométhing2()
|
| OnHallo()
|
| End Sub
|
| End Class
|
Das Ereignis wird nicht mehr direkt aufgerufen, sondern die geerbte Methode OnHallo, die ihrerseits die Ereignisauslösung richtig delegiert.
Sehen wir uns zum Abschluss den zusammengefassten Code an.
| ' ----------------------------------------------------------
|
| ' Beispiel: ...\Kapitel 6\Ereignisse
|
| ' ----------------------------------------------------------
|
| Module Module1
|
| Sub Main()
|
| Dim obj As New ClassB
|
| AddHandler obj.Hallo, AddressOf MyTestMethod
|
| obj.DoSomething2()
|
| Console.ReadLine()
|
| End Sub
|
| Public Sub MyTestMethod()
|
| Console.WriteLine("Ereignis ist ausgeloest.")
|
| End Sub
|
| End Module
|
| ' ---------- Basisklasse --------------
|
| Class ClassA
|
| Public Delegate Sub MyHandler()
|
| Public Event Hallo As MyHandler
|
| Public Sub DoSomething()
|
| OnHallo()
|
| End Sub
|
| Public Sub OnHallo()
|
| RaiseEvent Hallo()
|
| End Sub
|
| End Class
|
| ' ----------- Subklasse --------------
|
| Class ClassB
|
| Inherits ClassA
|
| Public Sub DoSomething2()
|
| OnHallo()
|
| End Sub
|
| End Class
|
|